/*
 * 这里只是一个配置的例子.
*/

#include "tiny_initer.h"
#include "uart.h"
#include "tiny_def.h"

#define SysTick_BASE (0xE000E000 + 0x0010UL)
#define SYSTICK_FRE (8000000) // Max: 16777215


#define SCB_Base (0xE000ED00)

#define SCB_ICSR_PENDSTCLR_Pos 25							   /*!< SCB ICSR: PENDSTCLR Position */
#define SCB_ICSR_PENDSTCLR_Msk (1ul << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
void SysTick_Handler(void);
void __memcpy(unsigned char *dst, unsigned char *src, unsigned int size);
void __memset(unsigned char *dst, unsigned char val, unsigned int size);
typedef struct
{
	volatile unsigned int CTRL;	 /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
	volatile unsigned int LOAD;	 /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
	volatile unsigned int VAL;	 /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
	volatile unsigned int CALIB; /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
} SysTick_Type;

typedef struct
{
	volatile unsigned int CPUID;   /*!< Offset: 0x00  CPU ID Base Register                                  */
	volatile unsigned int ICSR;	   /*!< Offset: 0x04  Interrupt Control State Register                      */
	volatile unsigned int VTOR;	   /*!< Offset: 0x08  Vector Table Offset Register                          */
	volatile unsigned int AIRCR;   /*!< Offset: 0x0C  Application Interrupt / Reset Control Register        */
	volatile unsigned int SCR;	   /*!< Offset: 0x10  System Control Register                               */
	volatile unsigned int CCR;	   /*!< Offset: 0x14  Configuration Control Register                        */
	volatile unsigned int SHP[12]; /*!< Offset: 0x18  System Handlers Priority Registers (4-7, 8-11, 12-15) */
	volatile unsigned int SHCSR;   /*!< Offset: 0x24  System Handler Control and State Register             */
	volatile unsigned int CFSR;	   /*!< Offset: 0x28  Configurable Fault Status Register                    */
	volatile unsigned int HFSR;	   /*!< Offset: 0x2C  Hard Fault Status Register                            */
	volatile unsigned int DFSR;	   /*!< Offset: 0x30  Debug Fault Status Register                           */
	volatile unsigned int MMFAR;   /*!< Offset: 0x34  Mem Manage Address Register                           */
	volatile unsigned int BFAR;	   /*!< Offset: 0x38  Bus Fault Address Register                            */
	volatile unsigned int AFSR;	   /*!< Offset: 0x3C  Auxiliary Fault Status Register                       */
	volatile unsigned int PFR[2];  /*!< Offset: 0x40  Processor Feature Register                            */
	volatile unsigned int DFR;	   /*!< Offset: 0x48  Debug Feature Register                                */
	volatile unsigned int ADR;	   /*!< Offset: 0x4C  Auxiliary Feature Register                            */
	volatile unsigned int MMFR[4]; /*!< Offset: 0x50  Memory Model Feature Register                         */
	volatile unsigned int ISAR[5]; /*!< Offset: 0x60  ISA Feature Register                                  */
} SCB_Type;

void SysTick_Init(void)
{
	SysTick_Type *SysTick = (SysTick_Type *)SysTick_BASE;
	
	/* 配置SysTick用系统频率除TINY_TICK_PER_SECOND - 1 得到1ms执行TINY_TICK_PER_SECOND个tick */
	SysTick->LOAD = SYSTICK_FRE / TINY_TICK_PER_SECOND - 1;
	SysTick->VAL = 0;
	/* select clk source, enable systick, enable exception
	 *  BIT[2] : clk source, process clk
	 *  BIT[1] : enable exception
	 *  BIT[0] : enable systick
	 */
	SysTick->CTRL = (1 << 1) | (1 << 0);
}

EXPORT_DRIVER(SysTick_Init);
extern void tiny_kernel_system_tick(void);
void SysTick_Handler(void)
{
	SCB_Type *scb = (SCB_Type *)(SCB_Base);

	tiny_kernel_system_tick();

	/* clear statu */
	scb->ICSR |= SCB_ICSR_PENDSTCLR_Msk;
}

void __memcpy(unsigned char *dst, unsigned char *src, unsigned int size)
{
	if (dst == src)
	{
		return;
	}
	while (size--)
	{
		*dst = *src;
		dst++;
		src++;
	}
}

void __memset(unsigned char *dst, unsigned char val, unsigned int size)
{
	while (size--)
	{
		*dst = val;
		dst++;
	}
}
